package schedule

import (
	"context"
	"fmt"
	"log"
	"math"
	"time"

	"WHY_GIN/config"
	"WHY_GIN/service"
	"WHY_GIN/utils"

	"github.com/adshao/go-binance/v2"
)

// TrxTradeScheduler TRX/USDT交易对定时任务调度器
type TrxTradeScheduler struct {
	client      *binance.Client
	symbol      string
	isRunning   bool
	stopChan    chan bool
	gridPercent float64
	usdtAmount  float64 // 每次交易的USDT金额
	lastPrice   float64 // 上次交易价格
	priceFilter *binance.PriceFilter
}

// NewTrxTradeScheduler 创建新的TRX交易调度器
func NewTrxTradeScheduler() *TrxTradeScheduler {
	// 从配置文件读取 Binance API 密钥
	apiKey := config.Cfg.Binance.APIKey
	secretKey := config.Cfg.Binance.SecretKey
	useTestnet := config.Cfg.Binance.UseTestnet

	// 验证API密钥是否已配置
	if apiKey == "" || secretKey == "" {
		log.Fatal("[ERROR] Binance API密钥未配置，请检查config.yaml文件")
	}

	// 根据配置设置网络模式
	if useTestnet {
		binance.UseTestnet = true
		fmt.Println("[INFO] TRX调度器使用测试网络模式")
	} else {
		fmt.Println("[INFO] TRX调度器使用正式网络模式")
	}

	// 创建币安客户端
	client := binance.NewClient(apiKey, secretKey)

	// 初始化时间同步
	timeSyncManager := utils.GetTimeSyncManager()
	timeSyncManager.AutoSync(client)

	return &TrxTradeScheduler{
		client:      client,
		symbol:      "TRXUSDT",
		isRunning:   false,
		stopChan:    make(chan bool),
		gridPercent: 0.008, // 默认0.8%网格间隔，运行时会根据时间动态调整
		usdtAmount:  40.0,  // 每次交易40 USDT
		lastPrice:   0,
	}
}

// getGridPercentByTime 获取网格间距（统一使用0.8%）
func (s *TrxTradeScheduler) getGridPercentByTime() float64 {
	// 统一使用0.8%网格间距
	return 0.008
}

// Start 启动定时任务
func (s *TrxTradeScheduler) Start() error {
	if s.isRunning {
		return fmt.Errorf("TRX调度器已在运行中")
	}

	fmt.Println("[INFO] 启动TRX/USDT定时交易调度器...")

	// 同步服务器时间
	_, err := s.client.NewSetServerTimeService().Do(context.Background())
	if err != nil {
		return fmt.Errorf("TRX调度器服务器时间同步失败: %v", err)
	}
	fmt.Println("[SUCCESS] TRX调度器服务器时间同步完成")

	// 获取交易对信息
	err = s.initTradingPairInfo()
	if err != nil {
		return fmt.Errorf("TRX调度器初始化交易对信息失败: %v", err)
	}

	// 获取初始价格
	s.lastPrice, err = s.getCurrentPrice()
	if err != nil {
		return fmt.Errorf("TRX调度器获取初始价格失败: %v", err)
	}
	fmt.Printf("[INFO] TRX初始价格: %.8f USDT\n", s.lastPrice)

	s.isRunning = true

	// 启动定时任务
	go s.runScheduler()

	fmt.Println("[SUCCESS] TRX/USDT定时交易调度器已启动，每1秒检查一次交易条件")
	return nil
}

// Stop 停止定时任务
func (s *TrxTradeScheduler) Stop() {
	if !s.isRunning {
		fmt.Println("[INFO] TRX调度器未在运行")
		return
	}

	fmt.Println("[INFO] 正在停止TRX/USDT定时交易调度器...")
	s.isRunning = false
	s.stopChan <- true
	fmt.Println("[SUCCESS] TRX/USDT定时交易调度器已停止")
}

// runScheduler 运行定时调度器
func (s *TrxTradeScheduler) runScheduler() {
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			// 记录当前网格间距
			oldGridPercent := s.gridPercent
			// 动态调整网格间距
			s.gridPercent = s.getGridPercentByTime()

			// 检测网格间距变化
			if oldGridPercent != s.gridPercent && oldGridPercent != 0 {
				currentPrice, err := s.getCurrentPrice()
				if err == nil {
					s.lastPrice = currentPrice
				}
			}

			// 检查交易条件并执行交易
			err := s.checkAndExecuteTrade()
			if err != nil {
				fmt.Printf("[ERROR] TRX交易检查执行失败: %v\n", err)
			}
		case <-s.stopChan:
			fmt.Println("[INFO] TRX调度器收到停止信号，退出调度器")
			return
		}
	}
}

// checkAndExecuteTrade 检查交易条件并执行交易
func (s *TrxTradeScheduler) checkAndExecuteTrade() error {
	// 获取当前价格
	currentPrice, err := s.getCurrentPrice()
	if err != nil {
		return fmt.Errorf("获取TRX当前价格失败: %v", err)
	}

	// 计算价格变化百分比
	priceChangePercent := (currentPrice - s.lastPrice) / s.lastPrice

	fmt.Printf("[DEBUG] TRX当前价格: %.8f, 上次价格: %.8f, 变化: %.4f%%\n",
		currentPrice, s.lastPrice, priceChangePercent*100)

	// 检查是否触发交易条件
	if s.shouldTriggerTrade(priceChangePercent) {
		fmt.Printf("[INFO] TRX触发交易条件，价格变化: %.4f%%\n", priceChangePercent*100)

		// 执行网格交易
		err = s.executeGridTrade(currentPrice)
		if err != nil {
			fmt.Printf("[ERROR] TRX网格交易执行失败: %v\n", err)
			return err
		}

		// 更新最后价格（只有成交时才更新lastPrice）
		s.lastPrice = currentPrice
		fmt.Printf("[SUCCESS] TRX交易执行完成，更新基准价格为: %.8f\n", s.lastPrice)
	}

	return nil
}

// shouldTriggerTrade 判断是否应该触发交易
func (s *TrxTradeScheduler) shouldTriggerTrade(priceChangePercent float64) bool {
	// 当价格变化超过网格间隔的一半时触发交易
	triggerThreshold := s.gridPercent / 2

	fmt.Printf("[DEBUG] TRX网格间距: %.3f%%, 触发阈值: %.3f%%, 价格变化: %.4f%%\n",
		s.gridPercent*100, triggerThreshold*100, priceChangePercent*100)

	// 价格上涨或下跌超过阈值时触发
	shouldTrigger := priceChangePercent > triggerThreshold || priceChangePercent < -triggerThreshold

	return shouldTrigger
}

// executeGridTrade 执行网格交易
func (s *TrxTradeScheduler) executeGridTrade(currentPrice float64) error {
	fmt.Printf("[INFO] 开始执行TRX网格交易，当前价格: %.8f\n", currentPrice)

	// 网格层数：重复5次，形成网格结构
	gridLevels := 5
	successfulOrders := 0
	totalOrders := 0

	// 循环执行5次，每次在不同价格层级下单
	for i := 1; i <= gridLevels; i++ {
		// 计算每层的价格偏移（逐层递增）
		priceOffset := float64(i) * s.gridPercent
		
		// 生成买单和卖单价格
		buyPrice := currentPrice * (1 - priceOffset)
		sellPrice := currentPrice * (1 + priceOffset)

		// 验证价格有效性
		if buyPrice <= 0 {
			fmt.Printf("[WARNING] TRX第%d层买入价格无效: %.8f，跳过此层\n", i, buyPrice)
			continue
		}

		// 根据USDT金额计算对应的TRX数量（TRX步长需要根据实际情况调整）
		buyQuantity := math.Floor(s.usdtAmount / buyPrice)
		sellQuantity := math.Floor(s.usdtAmount / sellPrice)
		
		// 验证数量有效性
		if buyQuantity <= 0 {
			fmt.Printf("[WARNING] TRX第%d层买入数量计算结果无效: %.0f TRX，跳过买单\n", i, buyQuantity)
		} else {
			// 下买单
			fmt.Printf("[INFO] TRX第%d层买单: %s @ %.8f USDT, 目标金额: %.2f USDT, 数量: %.0f TRX\n", i, s.symbol, buyPrice, s.usdtAmount, buyQuantity)
			totalOrders++
			err := s.placeLimitOrderWithQuantity(binance.SideTypeBuy, buyPrice, buyQuantity)
			if err != nil {
				fmt.Printf("[ERROR] TRX第%d层买单下单失败: %v\n", i, err)
			} else {
				fmt.Printf("[SUCCESS] TRX第%d层买单下单成功: %s @ %.8f USDT, 数量: %.0f TRX\n", i, s.symbol, buyPrice, buyQuantity)
				successfulOrders++
			}
		}

		if sellQuantity <= 0 {
			fmt.Printf("[WARNING] TRX第%d层卖出数量计算结果无效: %.0f TRX，跳过卖单\n", i, sellQuantity)
		} else {
			// 下卖单
			fmt.Printf("[INFO] TRX第%d层卖单: %s @ %.8f USDT, 目标金额: %.2f USDT, 数量: %.0f TRX\n", i, s.symbol, sellPrice, s.usdtAmount, sellQuantity)
			totalOrders++
			err := s.placeLimitOrderWithQuantity(binance.SideTypeSell, sellPrice, sellQuantity)
			if err != nil {
				fmt.Printf("[ERROR] TRX第%d层卖单下单失败: %v\n", i, err)
			} else {
				fmt.Printf("[SUCCESS] TRX第%d层卖单下单成功: %s @ %.8f USDT, 数量: %.0f TRX\n", i, s.symbol, sellPrice, sellQuantity)
				successfulOrders++
			}
		}

		// 每层之间添加短暂延迟，避免API限制
		if i < gridLevels {
			time.Sleep(100 * time.Millisecond)
		}
	}

	fmt.Printf("[INFO] TRX网格交易执行完成: 成功下单 %d/%d\n", successfulOrders, totalOrders)
	return nil
}

// placeLimitOrderWithQuantity 下限价单（支持动态数量）
func (s *TrxTradeScheduler) placeLimitOrderWithQuantity(side binance.SideType, price float64, quantity float64) error {
	// 验证数量有效性
	if quantity <= 0 {
		return fmt.Errorf("无效的TRX交易数量: %.0f TRX", quantity)
	}
	// 调用service包中的浮点数量下单函数
	return service.PlaceLimitOrderWithFloatQuantity(s.client, s.symbol, side, price, quantity, s.priceFilter.TickSize)
}

// getCurrentPrice 获取当前市场价格
func (s *TrxTradeScheduler) getCurrentPrice() (float64, error) {
	prices, err := s.client.NewListPricesService().Symbol(s.symbol).Do(context.Background())
	if err != nil {
		fmt.Printf("[ERROR] TRX API调用失败: %v\n", err)
		return 0, err
	}

	for _, price := range prices {
		if price.Symbol == s.symbol {
			priceFloat, err := service.ParseFloat(price.Price)
			if err != nil {
				fmt.Printf("[ERROR] TRX价格解析失败: %s -> %v\n", price.Price, err)
				return 0, err
			}

			// 价格异常检测：如果价格变化超过50%，记录警告并进行二次验证
			if s.lastPrice > 0 {
				changePercent := (priceFloat - s.lastPrice) / s.lastPrice
				if changePercent > 0.5 || changePercent < -0.5 {
					fmt.Printf("[WARNING] 检测到TRX异常价格变化: 从%.8f到%.8f，变化%.2f%%\n",
						s.lastPrice, priceFloat, changePercent*100)

					// 进行二次验证：等待1秒后重新获取价格
					fmt.Printf("[INFO] 进行TRX价格二次验证...\n")
					time.Sleep(1 * time.Second)

					// 重新获取价格进行验证
					verifyPrices, verifyErr := s.client.NewListPricesService().Symbol(s.symbol).Do(context.Background())
					if verifyErr == nil {
						for _, verifyPrice := range verifyPrices {
							if verifyPrice.Symbol == s.symbol {
								verifyPriceFloat, parseErr := service.ParseFloat(verifyPrice.Price)
								if parseErr == nil {
									fmt.Printf("[INFO] TRX二次验证价格: %.8f\n", verifyPriceFloat)
									// 如果两次价格差异很大，使用上次价格
									if math.Abs(priceFloat-verifyPriceFloat)/priceFloat > 0.1 {
										fmt.Printf("[ERROR] TRX价格数据不一致，使用上次价格: %.8f\n", s.lastPrice)
										return s.lastPrice, nil
									}
									// 使用验证后的价格
									priceFloat = verifyPriceFloat
								}
								break
							}
						}
					}
				}
			}

			return priceFloat, nil
		}
	}

	return 0, fmt.Errorf("未找到%s的市场价格", s.symbol)
}

// initTradingPairInfo 初始化交易对信息
func (s *TrxTradeScheduler) initTradingPairInfo() error {
	exchangeInfo, err := s.client.NewExchangeInfoService().Symbol(s.symbol).Do(context.Background())
	if err != nil {
		return err
	}

	// 查找价格过滤器
	for _, symbolInfo := range exchangeInfo.Symbols {
		if symbolInfo.Symbol == s.symbol {
			s.priceFilter = symbolInfo.PriceFilter()
			break
		}
	}

	if s.priceFilter == nil {
		return fmt.Errorf("未找到%s的价格过滤器规则", s.symbol)
	}

	fmt.Printf("[INFO] TRX价格过滤器规则: 最小价格=%s, 最大价格=%s, 价格精度=%s\n",
		s.priceFilter.MinPrice, s.priceFilter.MaxPrice, s.priceFilter.TickSize)

	return nil
}

// IsRunning 检查调度器是否正在运行
func (s *TrxTradeScheduler) IsRunning() bool {
	return s.isRunning
}

// GetStatus 获取调度器状态信息
func (s *TrxTradeScheduler) GetStatus() map[string]interface{} {
	return map[string]interface{}{
		"symbol":      s.symbol,
		"isRunning":   s.isRunning,
		"gridPercent": s.gridPercent,
		"usdtAmount":  s.usdtAmount,
		"lastPrice":   s.lastPrice,
		"tickSize":    s.priceFilter.TickSize,
	}
}